/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation
**
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
**     the names of its contributors may be used to endorse or promote
**     products derived from this software without specific prior written
**     permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/



// System Includes.
#include <e32std.h>
#include <e32base.h>

// User Includes.
#include "stringrenderer_symbian.h"
#include "descriptorexamples_symbian.h"

/*!
 * -----------------------------------------------------------------------------
 * This example method is documented in header file "DescriptorExamples.h"
 * -----------------------------------------------------------------------------
 */
void CDescriptorExamples::OnStack()
    {
    TPtr output( iViewer->GetViewBuffer() );
    
    //Note, You should use the _LIT macro instead of _L
    _LIT(KStack, "OnStack");
     RenderHeader(KStack, output );

    // --------------------
    // declare constant buffers to stack as automatic variable:
    // length=0, maxsize=20, data="".
    // Note that these automatic variables consumes stack until the
    // method ends...
    _LIT(KString1, "Hey!");
    TBufC<20> tbufc20(KString1);
    RenderVariableFormatted( tbufc20.Des(), output, KRenderCharacteristics );

    // --------------------
    // declare modifiable buffers to stack as automatic variable:
    // length=0, maxsize=20, data=""
    TBuf<20> tbuf20;
    RenderVariableFormatted( tbuf20, output, KRenderCharacteristics );
    _LIT(KString2, "HelloWorld");

    // --------------------
    // declare a non modifying descriptor pointer that points to array in
    // the middle of a temporary buffer: length=3, data="loWo"
    // Example is declared to own code block so automatic variables are
    // deleted when block ends.
        {
        TBuf<20> tmpBuf(KString2);
        const TText* arrayInBuf = tmpBuf.Ptr(); // point to first char in buffer
        TPtrC partOfBuffer( arrayInBuf + 3, 4 );
        RenderVariableFormatted( tmpBuf, output,
                                 KRenderCharacteristics );
        RenderVariableFormatted( partOfBuffer, output,
                                 KRenderCharacteristics );
        } // tmpBuf, arrayInBuf and partOfBuffer do no more exist in stack

    // --------------------
    // declare modifying buffer pointer pointing to memory
    // in another buffer: length=4, maxSize=5, data=loWo
        {
        // tmpBuf below can't be edited with its methods but we can alter data
        // through modifiable buffer pointer created few lines later
        TBufC<20> tmpBuf(KString2);
        // Set arrayInBuf to point to first character in buffer. Has to be
        // cast to non const pointer since TPtr expects such (of course)
        TText* arrayInBuf = (TText*)tmpBuf.Ptr();
        TPtr modifyingPointer( arrayInBuf + 3, 4, 5 );
        RenderVariableFormatted( modifyingPointer, output,
                                 KRenderCharacteristics );
        }

    // --------------------
    // declare modifying buffer pointing to a buffer descriptor - instead of
    // of its buffer directrly. The only way to do a such is to call method
    // Des() of non modifiable descriptors buffers TBufC and HBuf.
    // contents of tmpBuf after modification: length=6, maxlength=20,
    // data="HWorld"
        {
        TBufC<20> originalBuf(KString2);
        TPtr tmpBufPtr = originalBuf.Des();
        // modify the original buffer. Length in both descriptors
        // is updated!
        tmpBufPtr.Delete(1, 4);
        RenderVariableFormatted( originalBuf.Des(), output,
                                 KRenderCharacteristics );
        }
    iViewer->UpdateView();
    }

/*!
 * -----------------------------------------------------------------------------
 * This example method is documented in header file "DescriptorExamples.h"
 * -----------------------------------------------------------------------------
 */
void CDescriptorExamples::OnHeapL()
    {
    _LIT(KHeap, "OnHeap");
    TPtr output( iViewer->GetViewBuffer() );
    RenderHeader(KHeap, output );

    // --------------------
    // Allocate heap buffer with buffer size of 512. Factory
    // method LC allocates the object, pushes cleanup item to
    // cleanup stack and returns pointer to allocated object.
    //
    HBufC *hbufc = HBufC::NewLC( 512 );
    RenderVariableFormatted( hbufc->Des(), output, KRenderCharacteristics );

    // --------------------
    // Allocate TBuf descriptor with the same characteristics
    // like example above. Let also the constructor to initialize
    // the buffer with text.
    _LIT(KString3,"Hello World!");
    TBuf<512> *tbuf = new (ELeave) TBuf<512>(KString3);
    // Objects allocated from heap have to be deleted explicitly. Quite good
    // practise is to push every item allocated from heap to cleanup stack and
    // let the last line in method delete all allocated objects with one method
    // call (CleanupStack::PopAndDestroy(count)). If method leaves at the middle
    // of execution, the trap harness deletes automatically all objects pushed
    // to cleanup stack and no memory leaks occur.
    CleanupStack::PushL( tbuf );
    RenderVariableFormatted( *tbuf, output, KRenderCharacteristics );

    // we do no more need allocated objects, so lets remove them from cleanup
    // stack with one method call.
    CleanupStack::PopAndDestroy(2); // hbufc & tbuf
    iViewer->UpdateView();
    }

/*!
 * -----------------------------------------------------------------------------
 * This example method is documented in header file "DescriptorExamples.h"
 * -----------------------------------------------------------------------------
 */
void CDescriptorExamples::Literals()
    {
    _LIT(KLiteral,"Literals");
    TPtr output( iViewer->GetViewBuffer() );
    RenderHeader(KLiteral, output);

    // --------------------
    // Declare variable KLit1 and assing some text to it. _LIT macro
    // evaluates so that static constant variable is declared and
    // initialized with given string data. Since static and constant,
    // it is compiled as part of program binary.
    _LIT( KLit1, "String declared with macro _LIT" );
    RenderVariableFormatted( KLit1, output, KRenderCharacteristics );

    // --------------------
    // Literals can be also created with macro _L. However, it isn't
    // so efficient (refer book "Symbian OS C++ for Mobile Phones"
    // for details). Using it in test code is acceptable.
    TPtrC L1 = _L( "String declared with macro _L" );
    RenderVariableFormatted( L1, output, KRenderCharacteristics );

    // --------------------
    // Let's declare a literal that contains euro sign (0x20AC).Since it
    // doesn't exist in many 8 bit encodings , we declare it as 'e' when
    // building non-unicode build
#ifdef _UNICODE
    // note that in unicode literal the unicode chars can be declared
    // by passing the unicode number of the character as hexadecimal number
    _LIT( KLitEuro, "I won 166\x20AC from lottery!" );
#else
    _LIT( KLitEuro, "I won 166e from lottery!" );
#endif
    RenderVariableFormatted( KLitEuro, output, KRenderCharacteristics );
    iViewer->UpdateView();
    }
